import { compileToFunction } from "./compiler";
import { callHook, mountComponent } from "./lifecycle";
import { initState } from "./state";
import { mergeOptions } from "./utils";

// 给Vue增加init方法
export function initMixin(Vue) {
  // 初始化方法
  Vue.prototype._init = function (options) {
    const vm = this;
    // 保存一份options到全局方便使用
    // mixin定义的过滤器/指令等都会挂在实例上
    vm.$options = mergeOptions(this.constructor.options,options);
    // 执行生命周期
    callHook(vm,"beforeCreate");
    // 初始化状态
    initState(vm);
    callHook(vm,"created");
    // 如果用户传el了,就挂载到此节点上
    if (options.el) {
      // 实现数据的挂载
      vm.$mount(options.el);
    }
  }
  // 挂载实例方法
  Vue.prototype.$mount = function (el) {
    const vm = this;
    const ops = vm.$options;
    el = document.querySelector(el);
    // 先找写没写render,写了render就不用管了,直接用
    if (!ops.render) {
      let template;
      if (!ops.template && el) {
        // 没写template但写el了
        template = el.outerHTML;
      } else{
        // 写了template和el就直接用template
        template = ops.template;
      }
      if (template) {
        // 如果有template就要对template进行编译
        const render = compileToFunction(template);
        ops.render = render;
      }
    }
    // 到这里就可以获得render方法了
    callHook(vm,'beforeMount');
    // 挂载组件实例
    mountComponent(vm,el);
    callHook(vm,'mounted');
  }
}